//----------------------------------------------------------
// Graphics_GameDX.cpp
//   Game-specific implementation of Graphics_GameDX class
//   DirectX support
//----------------------------------------------------------

#include "Graphics_GameDX.h"

extern int screenWidth;
extern int screenHeight;

// define custom vertex, U/V are texture coordinates
struct YACVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL; FLOAT U, V;};
#define YACFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)


Graphics_GameDX::Graphics_GameDX() 
{
	// initialize variables
	_pD3D = NULL;
	_pD3DDevice = NULL;

	_pvCamPos = new D3DXVECTOR3(10.0f, 20.0f, 55.0f);
	_pvCamLook = new D3DXVECTOR3(10.0f, 0.0f, 0.0f);
	_pvCamUp = new D3DXVECTOR3(0.0f, 1.0f, 0.0f);
}

Graphics_GameDX::~Graphics_GameDX()
{
	// clean up objects
	delete _pvCamPos;
	delete _pvCamLook;
	delete _pvCamUp;
}

bool Graphics_GameDX::Initialize(Engine *pEngine)
{
	_engine = pEngine;
	_wndHandle = _engine->GetWindow();

	// create the DirectX object
	if (NULL == (_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
	{
		return false;
	}

	// create the presentation parameters structure	
	D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;	// sets the back buffer to 32-bit
	d3dpp.BackBufferCount  = 1;
	d3dpp.BackBufferHeight = screenWidth;
	d3dpp.BackBufferHeight = screenHeight;
	d3dpp.hDeviceWindow    = *_wndHandle;
	d3dpp.EnableAutoDepthStencil = TRUE;		// enables depth
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;	// depth stencil of 16bit

	// create the DirectX device
    if ( FAILED( _pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, *_wndHandle,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &_pD3DDevice ) ) )
    {
        return false;
    }

	//_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);	//turn off 3D lighting
	//face culling based upon viewport
	//_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	//_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); //turn on z-buffer
	//_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
	//ambient light
	//_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(85, 85, 85));

	//_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
	//set shade mode
	//accepts the values: D3DSHADE_FLAT, D3DSHADE_GOURAUD, D3DSHADE_PHONG
	//_pD3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); //GOURAUD is default
	
    //D3DMATERIAL9 material;    // create the material struct

    //ZeroMemory(&material, sizeof(D3DMATERIAL9));    // clear out the struct for use
    //material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set diffuse color to white
    //material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set ambient color to white
	////material.Emissive = D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f);

    //_pD3DDevice->SetMaterial(&material);    // set the globably-used material to &material

	// lights
	//PointLight0 - red
	//D3DLIGHT9 PointLight;
	//ZeroMemory( &PointLight, sizeof(D3DLIGHT9) );
	//PointLight.Type = D3DLIGHT_POINT;
	//PointLight.Diffuse.r = 1.0f;
	//PointLight.Diffuse.g = 0.0f;
	//PointLight.Diffuse.b = 0.0f;
	//PointLight.Attenuation0 = 0.1f;
	////PointLight.Falloff = 100.0f;
	////PointLight.Attenuation0 = 0.0f;
	////PointLight.Attenuation1 = 1.0f;
	////PointLight.Attenuation2 = 0.0f;
	//PointLight.Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	//PointLight.Range = 10.0f;

	// Tell the device about the light and turn it on
	//_pD3DDevice->SetLight( 0, &PointLight );
	//_pD3DDevice->LightEnable( 0, TRUE );

	return true;
}

bool Graphics_GameDX::Update(float deltaTime)
{
	// do something
	return true;
}

bool Graphics_GameDX::Shutdown()
{
	// release objects
	if (_pD3DDevice != NULL) _pD3DDevice->Release();
    if (_pD3D != NULL) _pD3D->Release();

	return true;
}

bool Graphics_GameDX::RenderStart()
{
	// fail is DirectX Device is not valid
	if (NULL == _pD3DDevice) return false;

    // clear the back and z buffers
    _pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0 );
	_pD3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
	
	// set the vertex format
	_pD3DDevice->SetFVF(YACFVF);

	// begin scene
	_pD3DDevice->BeginScene();

	return true;
}

void Graphics_GameDX::RenderEnd()
{
	// end scene
	_pD3DDevice->EndScene();

	// move back buffer to the screen
    _pD3DDevice->Present(NULL, NULL, NULL, NULL);
}